package com.lbssoft.gpsbd.config.shiro;

import com.alibaba.fastjson.JSON;
import com.lbssoft.gpsbd.common.Constant;
import com.lbssoft.gpsbd.config.redis.RedisUtils;
import com.lbssoft.gpsbd.model.Permission;
import com.lbssoft.gpsbd.model.User;
import com.lbssoft.gpsbd.model.vo.UserVo;
import com.lbssoft.gpsbd.service.PermissionService;
import com.lbssoft.gpsbd.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;

import java.util.ArrayList;
import java.util.List;

public class MyRealm extends AuthorizingRealm {

    @Autowired
    @Lazy
    private UserService userService;

    @Autowired
    @Lazy//解决redis初始化的问题
    private PermissionService permissionService;

    @Autowired
    private RedisUtils redisUtils;

    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof MyToken;
    }

    /**
     * 只有当需要检测用户权限的时候才会调用此方法，例如checkRole,checkPermission之类的
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
    	//System.out.println("授权");
		// 根据用户名查找角色，请根据需求实现
		UserVo user = (UserVo) principals.getPrimaryPrincipal();
       // System.out.println(JSON.toJSON(user));
		SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        //根据token获取用户的角色和权限
        String[] roleIds = user.getRoleIds().split(",");
        List<Permission> permissions  = new ArrayList<>();
        for(String roleId:roleIds){
            permissions.addAll(permissionService.getPermissionsByRoleId(Integer.parseInt(roleId)));
        }

        String[] roles = user.getRoleKeys().split(",");
        for(String role:roles){
            authorizationInfo.addRole(role);
        }

        for(Permission permis:permissions ){
          if(permis.getPermis()!=null&&!permis.getPermis().equals("")){
              authorizationInfo.addStringPermission(permis.getPermis());
          }

        }

		return authorizationInfo;
    }

    /**
     * 默认使用此方法进行用户名正确与否验证，错误抛出异常即可。
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken auth) throws AuthenticationException {
        String token = (String) auth.getCredentials();
        if (token == null) {
            throw new AuthenticationException("token invalid");
        }
        UserVo user = userService.getUserByToken(token);
        if (user == null) {
            throw new AuthenticationException(); //如果密码错误
        }
        redisUtils.setExpire(Constant.REDIS_CACHE_PREFIX+":token:token_"+user.getToken(),Constant.REDIS_CACHE_TOKEN_EXPIRE);
         // 然后进行客户端消息摘要和服务器端消息摘要的匹配
     	return new SimpleAuthenticationInfo(user,token,getName());
    }
}
